package com.zhanghao.ems.utils;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.lowagie.text.Document;
import com.lowagie.text.pdf.PdfCopy;
import com.lowagie.text.pdf.PdfImportedPage;
import com.lowagie.text.pdf.PdfReader;

import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;

import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

public class PDFUtils {
    public static PDRectangle getPDRectangleForField(PDField field) {
        COSBase rectArray = field.getCOSObject().getDictionaryObject(
                "Rect");
        PDRectangle pdrect = new PDRectangle(0, 0);
        if (rectArray instanceof COSArray) {
            pdrect = new PDRectangle((COSArray) rectArray);
        } else if (rectArray != null && rectArray.getCOSObject() instanceof COSArray) {
            pdrect = new PDRectangle((COSArray) rectArray.getCOSObject());
        }
        return pdrect;
    }

    public static void addMultipleLines(PDDocument pdf, String text, PDFont font,
            float fontSize, PDRectangle rectangle, String align) throws IOException {
        if (text == null) {
            return;
        }
        PDPage page = pdf.getPage(0);
        PDPageContentStream contentStream = new PDPageContentStream(pdf, page,
                PDPageContentStream.AppendMode.APPEND, true, true);
        String[] forceLines = text.split("\n");

        List<String> lines = new ArrayList<String>();
        float leading = 1.2f * fontSize;

        for (String line : forceLines) {
            String[] chars = line.split("");
            String currentLine = "";
            for (int i = 0; i < chars.length; i++) {
                currentLine += chars[i];
                float size = fontSize * font.getStringWidth(currentLine) / 1000;
                if (size > rectangle.getWidth()) {
                    lines.add(currentLine.substring(0, currentLine.length() - 1));
                    // System.out.printf("'%s' is line\n",
                    // currentLine.substring(0,currentLine.length()-1));
                    currentLine = chars[i];
                }
            }
            lines.add(currentLine);

        }

        contentStream.beginText();
        contentStream.setFont(font, fontSize);
        float currentY = rectangle.getUpperRightY();
        float currentX = rectangle.getLowerLeftX();

        float currentPositionX = 0;

        for (String line : lines) {
            // currentY -=leading;
            float size = fontSize * font.getStringWidth(line) / 1000;
            float offset = 0;
            if ("center".equals(align)) {
                offset = (rectangle.getWidth() - size) / 2;
            } else if ("right".equals(align)) {
                offset = rectangle.getWidth() - size;
            }

            // currentOffset = offset;
            contentStream.newLineAtOffset(currentX + offset - currentPositionX, currentY - leading);
            contentStream.showText(line);
            // 记录当前输入位置
            currentPositionX = currentX + offset;
            currentY = 0;
            // contentStream.newLineAtOffset(0, -leading);
        }
        contentStream.endText();
        contentStream.close();

    }

    public static BufferedImage convertPdf2Image(PDDocument document, float dpi)
            throws Exception {

        // 为了保证显示清除，至少 90
        if (dpi < 90) {
            dpi = 90;
        }

        PDFRenderer pdfRenderer = new PDFRenderer(document);
        BufferedImage image = pdfRenderer.renderImageWithDPI(0, dpi, ImageType.RGB);
        document.close();
        // ImageIO.write(image, "png", outputStream);
        return image;
    }

    public static byte[] generateBarCode(String code) throws WriterException, IOException {
        String text = code;
        int width = 90;
        int height = 10;
        String format = "png";
        Hashtable hints = new Hashtable();
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.CODE_128, width, height, hints);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        MatrixToImageWriter.writeToStream(bitMatrix, format, outputStream);
        byte[] bytes = outputStream.toByteArray();
        return bytes;

    }

    /**
     * @param acroForm
     * @desc 清除表单输入框
     */
    public static void clearForm(PDAcroForm acroForm) {

        List<PDField> fields = acroForm.getFields();
        if (fields == null) {
            return;
        }
        for (PDField field : fields) {
            field.setReadOnly(true);

        }
    }

    /**
     * 
     * @param source 需要进行合并的pdf文件流
     * @param target 文件合并目标文档
     * @param writer PdfCopy
     * @throws IOException
     */
    public static void cantact(InputStream source, Document target, PdfCopy writer) throws IOException {

        PdfReader reader = new PdfReader(new BufferedInputStream(source));
        reader.consolidateNamedDestinations();
        // we retrieve the total number of pages
        int numberOfPages = reader.getNumberOfPages();

        // we add content
        PdfImportedPage page;
        for (int j = 1; j <= numberOfPages; j++) {
            page = writer.getImportedPage(reader, j);
            writer.addPage(page);
        }
        writer.freeReader(reader);

    }
}
